--[[  comboLib.lua v1.0

         by llama

]]
do
    local itemArray = {
        { name = "DFG", id = 3128 },
        { name = "HXG", id = 3146 },
        { name = "BWC", id = 3144 }
    }

    comboLib = {}
    local usableArray = {}
    local player = GetMyHero()
    local comboArray = {}
    local comboStorage = {}
    local skillCountArray = {}
    local skillCount
    local igniteName = "SummonerDot"

    local function checkItems()
        local ItemSlot = { ITEM_1, ITEM_2, ITEM_3, ITEM_4, ITEM_5, ITEM_6, }

        for i = 1, #comboArray, 1 do
            for j = 1, #itemArray, 1 do
                if comboArray[i].name == itemArray[j].name then

                    comboArray[i].isItem = true
                    comboArray[i].slot = nil

                    for k = 1, #ItemSlot, 1 do
                        if player:getInventorySlot(ItemSlot[k]) == itemArray[j].id then
                            comboArray[i].slot = ItemSlot[k]
                            comboArray[i].skill = ItemSlot[k]
                        end
                    end
                end
            end
        end
    end

    local function checkMana()

        for i = 1, #usableArray, 1 do
            usableArray[i].mana = player:GetSpellData(usableArray[i].skill).mana
        end
    end

    local function checkCooldown()

        for i = 1, #comboArray, 1 do
            if comboArray[i].isItem == true then
                if comboArray[i].slot == nil then
                    comboArray[i].offCooldown = false
                else
                    comboArray[i].offCooldown = player:CanUseSpell(comboArray[i].slot) == READY
                end
            else
                comboArray[i].offCooldown = (player:CanUseSpell(comboArray[i].skill) == READY)
            end
        end
    end

    local function checkRange(object)
        for i = 1, #comboArray, 1 do
            comboArray[i].isInRange = (player:GetDistance(object) <= comboArray[i].range)
        end
    end

    local function makeUsableCombo()
        local j = 1
        for i = 1, #comboArray, 1 do
            if comboArray[i].offCooldown == true and comboArray[i].isInRange == true and comboArray[i].dmg > 0 then
                usableArray[j] = comboArray[i]
                j = j + 1
            end
        end
    end

    local function checkSkillDamage(object)
        for i = 1, #comboArray, 1 do

            if comboArray.isItem == true then
                for j = 1, #itemArray, 1 do
                    if comboArray[i].name == itemArray[j].name then

                        comboArray[i].dmg = math.floor(getDmg(itemArray[j].name, object, player))
                    end
                end
            else
                comboArray[i].dmg = math.floor(getDmg(comboArray[i].name, object, player))
            end
        end
    end

    local function checkCombo(health)
        local totalDmg = 0
        local totalMana = 0
        local bestCombo = {}
        local usableMana = math.floor(player.mana)
        local length = #usableArray

        for i = 1, length, 1 do
            totalDmg = totalDmg + usableArray[i].dmg
            totalMana = totalMana + usableArray[i].mana
        end

        if totalDmg < health or totalMana > usableMana then
            return nil
        else
            if length >= 1 then
                for i = 1, length, 1 do
                    if usableArray[i].dmg > health then
                        if usableArray[i].mana < usableMana then
                            bestCombo[1] = usableArray[i]
                            return bestCombo
                        end
                    end
                end
            end
            if length >= 2 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        if i ~= j then
                            if usableArray[i].dmg + usableArray[j].dmg > health then
                                if usableArray[i].mana + usableArray[j].mana < usableMana then
                                    bestCombo[1] = usableArray[i]
                                    bestCombo[2] = usableArray[j]
                                    return bestCombo
                                end
                            end
                        end
                    end
                end
            end
            if length >= 3 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        for k = 1, length, 1 do
                            if i ~= j and j ~= k and i ~= k then
                                if usableArray[i].dmg + usableArray[j].dmg + usableArray[k].dmg > health then
                                    if usableArray[i].mana + usableArray[j].mana + usableArray[k].mana < usableMana then
                                        bestCombo[1] = usableArray[i]
                                        bestCombo[2] = usableArray[j]
                                        bestCombo[3] = usableArray[k]
                                        return bestCombo
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if length >= 4 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        for k = 1, length, 1 do
                            for l = 1, length, 1 do
                                if i ~= j and i ~= k and i ~= l and j ~= k and j ~= l and k ~= l then
                                    if usableArray[i].dmg + usableArray[j].dmg + usableArray[k].dmg + usableArray[l].dmg > health then
                                        if usableArray[i].mana + usableArray[j].mana + usableArray[k].mana + usableArray[l].mana < usableMana then
                                            bestCombo[1] = usableArray[i]
                                            bestCombo[2] = usableArray[j]
                                            bestCombo[3] = usableArray[k]
                                            bestCombo[4] = usableArray[l]
                                            return bestCombo
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if length >= 5 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        for k = 1, length, 1 do
                            for l = 1, length, 1 do
                                for m = 1, length, 1 do
                                    if i ~= j and i ~= k and i ~= l and i ~= m and j ~= k and j ~= l and j ~= m and k ~= l and k ~= m and l ~= m then
                                        if usableArray[i].dmg + usableArray[j].dmg + usableArray[k].dmg + usableArray[l].dmg + usableArray[m].dmg > health then
                                            if usableArray[i].mana + usableArray[j].mana + usableArray[k].mana + usableArray[l].mana + usableArray[m].mana < usableMana then
                                                bestCombo[1] = usableArray[i]
                                                bestCombo[2] = usableArray[j]
                                                bestCombo[3] = usableArray[k]
                                                bestCombo[4] = usableArray[l]
                                                bestCombo[5] = usableArray[m]
                                                return bestCombo
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if length >= 6 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        for k = 1, length, 1 do
                            for l = 1, length, 1 do
                                for m = 1, length, 1 do
                                    for n = 1, length, 1 do
                                        if i ~= j and i ~= k and i ~= l and i ~= m and i ~= n and j ~= k and j ~= l and j ~= m and j ~= n and k ~= l and k ~= m and k ~= n and l ~= m and l ~= n and m ~= n then
                                            if usableArray[i].dmg + usableArray[j].dmg + usableArray[k].dmg + usableArray[l].dmg + usableArray[m].dmg + usableArray[n].dmg > health then
                                                if usableArray[i].mana + usableArray[j].mana + usableArray[k].mana + usableArray[l].mana + usableArray[m].mana + usableArray[n].mana < usableMana then
                                                    bestCombo[1] = usableArray[i]
                                                    bestCombo[2] = usableArray[j]
                                                    bestCombo[3] = usableArray[k]
                                                    bestCombo[4] = usableArray[l]
                                                    bestCombo[5] = usableArray[m]
                                                    bestCombo[6] = usableArray[n]
                                                    return bestCombo
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if length >= 7 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        for k = 1, length, 1 do
                            for l = 1, length, 1 do
                                for m = 1, length, 1 do
                                    for n = 1, length, 1 do
                                        for o = 1, length, 1 do
                                            if i ~= j and i ~= k and i ~= l and i ~= m and i ~= n and i ~= o and j ~= k and j ~= l and j ~= m and j ~= n and j ~= o and k ~= l and k ~= m and k ~= n and k ~= o and l ~= m and l ~= n and l ~= o and m ~= n and m ~= o and n ~= o then
                                                if usableArray[i].dmg + usableArray[j].dmg + usableArray[k].dmg + usableArray[l].dmg + usableArray[m].dmg + usableArray[n].dmg + usableArray[o].dmg > health then
                                                    if usableArray[i].mana + usableArray[j].mana + usableArray[k].mana + usableArray[l].mana + usableArray[m].mana + usableArray[n].mana + usableArray[o].mana < usableMana then
                                                        bestCombo[1] = usableArray[i]
                                                        bestCombo[2] = usableArray[j]
                                                        bestCombo[3] = usableArray[k]
                                                        bestCombo[4] = usableArray[l]
                                                        bestCombo[5] = usableArray[m]
                                                        bestCombo[6] = usableArray[n]
                                                        bestCombo[7] = usableArray[o]
                                                        return bestCombo
                                                    end
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
            if length >= 8 then
                for i = 1, length, 1 do
                    for j = 1, length, 1 do
                        for k = 1, length, 1 do
                            for l = 1, length, 1 do
                                for m = 1, length, 1 do
                                    for n = 1, length, 1 do
                                        for o = 1, length, 1 do
                                            for p = 1, length, 1 do
                                                if i ~= j and i ~= k and i ~= l and i ~= m and i ~= n and i ~= o and i ~= p and j ~= k and j ~= l and j ~= m and j ~= n and j ~= o and j ~= p and k ~= l and k ~= m and k ~= n and k ~= o and k ~= p and l ~= m and l ~= n and l ~= o and l ~= p and m ~= n and m ~= o and m ~= p and n ~= o and n ~= p and o ~= p then
                                                    if usableArray[i].dmg + usableArray[j].dmg + usableArray[k].dmg + usableArray[l].dmg + usableArray[m].dmg + usableArray[n].dmg + usableArray[o].dmg + usableArray[p].dmg > health then
                                                        if usableArray[i].mana + usableArray[j].mana + usableArray[k].mana + usableArray[l].mana + usableArray[m].mana + usableArray[n].mana + usableArray[o].mana + usableArray[p].mana < usableMana then
                                                            bestCombo[1] = usableArray[i]
                                                            bestCombo[2] = usableArray[j]
                                                            bestCombo[3] = usableArray[k]
                                                            bestCombo[4] = usableArray[l]
                                                            bestCombo[5] = usableArray[m]
                                                            bestCombo[6] = usableArray[n]
                                                            bestCombo[7] = usableArray[o]
                                                            bestCombo[8] = usableArray[p]
                                                            return bestCombo
                                                        end
                                                    end
                                                end
                                            end
                                        end
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end

    local function checkDFG(combo)
        local tempcombo = {}
        local dfgNum
        local dfgFound = false
        for i = 1, #combo, 1 do
            if combo[i].name == "DFG" then
                tempcombo[1] = combo[i]
                dfgFound = true
                dfgNum = i
            end
        end

        if dfgFound then
            for i = 2, #combo, 1 do
                if i <= dfgNum then
                    tempcombo[i] = combo[i - 1]
                else
                    tempcombo[i] = combo[i]
                end
            end
            return tempcombo
        else
            return combo
        end
    end

    function comboLib:newSkill(skillName, skillRange, comboNum)
        local combo = {}
        skillName = string.upper(skillName)

        if comboNum == nil then
            comboNum = 1
        end

        if comboStorage[comboNum] == nil then
            comboStorage[comboNum] = { comboArray = {} }
        end

        if skillCountArray[comboNum] == nil then
            skillCountArray[comboNum] = 1
        end

        skillCount = skillCountArray[comboNum]
        skillCountArray[comboNum] = skillCountArray[comboNum] + 1

        if skillName~= "IGNITE" or (skillName=="IGNITE" and (player:GetSpellData(SUMMONER_1).name==igniteName or player:GetSpellData(SUMMONER_2).name==igniteName)) then
            comboStorage[comboNum].comboArray[skillCount] = { name = skillName, range = skillRange, isInRange = true, offCooldown = false, isItem = false, slot = nil, skill = nil, mana = 0 }
        end
        if skillName == "Q" or skillName == "QM" then
            comboStorage[comboNum].comboArray[skillCount].skill = _Q
        elseif skillName == "W" or skillName == "W" then
            comboStorage[comboNum].comboArray[skillCount].skill = _W
        elseif skillName == "E" or skillName == "EM" then
            comboStorage[comboNum].comboArray[skillCount].skill = _E
        elseif skillName == "R" then
            comboStorage[comboNum].comboArray[skillCount].skill = _R
        elseif skillName == "IGNITE" then
            if player:GetSpellData(SUMMONER_1).name == igniteName then
                comboStorage[comboNum].comboArray[skillCount].skill = SUMMONER_1
            elseif player:GetSpellData(SUMMONER_2).name == igniteName then
                comboStorage[comboNum].comboArray[skillCount].skill = SUMMONER_2
            end
        end
    end

    function comboLib:findBestCombo(target, comboNum)
        local bestCombo = {}
        if comboNum == nil then
            comboNum = 1
        end

        comboArray = comboStorage[comboNum].comboArray
        if target ~= nil and #comboArray > 0 then

            checkItems() --checks array for items

            checkCooldown() --checks array for cooldowns
            checkRange(target) --checks which skills can be used with given ranges from target

            usableArray = {} --resets array of usable skills/items

            checkSkillDamage(target) --runs a check on all skills to find their damage

            makeUsableCombo() --makes the array depending on cooldown and range
            if #usableArray > 0 then --array must have at least 1 skill/item

                checkMana() --collects skill mana costs in the usable array.
                bestCombo = checkCombo(math.floor(target.health)) --find the best combo to kill.

                if bestCombo and #bestCombo > 0 then
                    bestCombo = checkDFG(bestCombo) --find DFG, put it at the top of list.
                end
            end
        end
        return bestCombo
    end
end
